import java.util.*;
import java.net.*;

public class FetchPageThread extends Thread  {

	private final static int MAX_THREADS = 4;

	static ThreadController threadLimiter = new ThreadController( MAX_THREADS );

	static Map<String,String> pageDatabase = new HashMap<String,String>();   


	private URL pageToFetch;           

	public FetchPageThread (String pageAddress) {

		try {
			pageToFetch = new URL(pageAddress);
			setName(pageAddress);           
			start();                        
		} catch (MalformedURLException badURL) {
			System.out.println(pageAddress + " is bad URL.. not starting thread for this one!");
		}
	}

	public void run() {

		int ticket;             
		String webPageContent;         
		ArrayList<String> pageLinksFound;       

		ticket = threadLimiter.getPassCertificate();

		webPageContent     = loadPage(pageToFetch);
		pageLinksFound   = extractHyperTextLinks(webPageContent);

		System.out.println(getName() + " has " + pageLinksFound.size() + " links.");

		Enumeration<String> enums = Collections.enumeration(pageLinksFound);
		while(enums.hasMoreElements()) {
			String page = (String) enums.nextElement();

			if ( ! isAlreadyVisited(page) ) {

				markAsVisited(page);

				System.out.println(getName() + " --> " + page);

				new FetchPageThread(page);

			} else {
				// System.out.println("Is visited: " + page);
			}
		}
		threadLimiter.returnCertificate(ticket);

		try {
			Thread.sleep( (int) (Math.random()*200) );
		} catch (Exception e) {}
	}

	protected String loadPage(URL page) {
		HTTPUtills http;

		http = new HTTPUtills();
		return http.downloadWebPage(page);
	}

	protected ArrayList<String> extractHyperTextLinks(String page) {

		int lastPositionHyperlink = 0;           
		int positionOfEndOfURL;                  
		String link;                   
		ArrayList<String> bagOfLinks = new ArrayList<String>();  

		while(lastPositionHyperlink != -1 ) {
			lastPositionHyperlink = page.indexOf("http://", lastPositionHyperlink);

			if (lastPositionHyperlink != -1) {

				positionOfEndOfURL = page.indexOf(">", lastPositionHyperlink + 1 );

				link = page.substring(lastPositionHyperlink, positionOfEndOfURL);
				link = link.trim();
				if (link.endsWith("\"")) {
					link = link.substring(0, link.length() - 1 );
				}

				if (link.indexOf("#") != -1) {
					link = link.substring(0, link.indexOf("#"));
				}

				if ( link.endsWith(".gif") ||
						link.endsWith(".jpg")    ) {
					;
				} else {    
					bagOfLinks.add( link );
				}

				lastPositionHyperlink++;    
			}
		}
		return bagOfLinks;
	}
	protected boolean isAlreadyVisited(String pageAddr) {
		return pageDatabase.containsKey(pageAddr);
	}
	protected void markAsVisited(String pageAddr) {
		pageDatabase.put(pageAddr, pageAddr);  
	}
}

